## openai_server.py
from typing import Dict

from elasticsearch import Elasticsearch
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_elasticsearch import ElasticsearchStore
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_openai import ChatOpenAI
from pydantic import SecretStr

import config
from chat_history import ChatHistory
from config import (
    ELASTICSEARCH_KNOWLEDGE_BASE_INDEX
)
from config import OPENAI_API_KEY, OPEN_MODULE_NAME
from elasticsearch_client import ElasticsearchClient
# from intent_recognition import IntentRecognition
from knowledge_base import KnowledgeBase
from langchain_neo4j import Neo4jGraph, Neo4jVector


class Server:
    _instance = None  # 类级别的变量，存储单例
    index = ELASTICSEARCH_KNOWLEDGE_BASE_INDEX

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            # 在这里初始化实例，只有第一次调用时才会执行
            cls._instance.__initialized = False
        return cls._instance

    def __init__(self, es_client, knowledge_base, chat_history, embedding, llm, elastic_vector, graph: Neo4jGraph):
        if not hasattr(self, '__initialized'):  # 防止重复初始化
            self.es_client = es_client
            self.knowledge_base = knowledge_base
            self.chat_history = chat_history
            self.embedding = embedding
            self.llm = llm
            self.elastic_vector = elastic_vector
            self.graph = graph
            self.__initialized = True


def create_server():
    """Create and configure the Flask application."""
    # Initialize Elasticsearch
    es = Elasticsearch([config.ELASTICSEARCH_HOST],
                       # basic_auth=('elastic', '9yC56qA+29y06J0HE9uw'),  # 更改为你的Elasticsearch用户名和密码
                       request_timeout=30  # 设置请求超时时间
                       )

    # Create ElasticsearchClient
    es_client = ElasticsearchClient(es)

    # Initialize KnowledgeBase
    knowledge_base = KnowledgeBase(es_client)

    # Initialize ChatHistory
    chat_history = ChatHistory(es_client)

    # embedding = HuggingFaceEmbeddings(
    #     model_name="bert-base-chinese"
    #     )  # 选择一个预训练模型
    embedding = None

    llm = ChatOpenAI(openai_api_key=SecretStr(OPENAI_API_KEY), openai_api_base=config.OPEN_API_BASE,
                     model_name=OPEN_MODULE_NAME, max_retries=1,
                     # streaming=True,
                     callbacks=[], temperature=0.6)
    # ES知识库
    elastic_vector = ElasticsearchStore(
        index_name=config.ELASTICSEARCH_KNOWLEDGE_BASE_INDEX,
        es_url=config.ELASTICSEARCH_HOST,
        es_user=config.ELASTICSEARCH_USER,
        es_password=config.ELASTICSEARCH_PASSWORD,
        # basic_auth=('elastic', '9yC56qA+29y06J0HE9uw'),  # 更改为你的Elasticsearch用户名和密码
        embedding=embedding,
    )


    graph = Neo4jGraph(url=config.NEO4J_HOST, username=config.NEO4J_USER, password=config.NEO4J_PASSWORD,
                       database=config.NEO4J_DB)
    # Create App instance
    server = Server(es_client, knowledge_base, chat_history, embedding, llm, elastic_vector, graph)

    return server


store = {}


def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]


def clear_session_history(session_id: str):
    history = get_session_history(session_id)
    history.clear()  # 假设clear是清空历史记录的方法
